// ##############################
// ####  note:  bokeweilai common main fun
// ####  create:  TANWENHUI (twh:谭文辉)
// ####  date:   2024/6/18
// ##############################

#include "bkwl_common.h"
#include "bkwl_data.h"
#include "bkwl_network.h"
#include "bkwl_log.h"
#include "bkwl_event.h"
#include "cJSON.h"
// #include "ble_boarding.h"
#include "bkwl_bt.h"

#include "components/bluetooth/bk_ble.h"
#include "components/bluetooth/bk_dm_ble.h"
#include "components/bluetooth/bk_dm_bluetooth.h"
// typedef struct
// {
// 	ble_boarding_info_t boarding_info;
// 	uint16_t channel;
// } doorbell_boarding_info_t;
static doorbell_boarding_info_t *doorbell_boarding_info = NULL;
static void doorbell_boarding_operation_handle(uint16_t opcode, uint16_t length, uint8_t *data)
{
	tprintf("doorbell_boarding_operation_handle opcode: %04X, length: %u\n", opcode, length);

	switch (opcode)
	{
	case BOARDING_OP_STATION_START:
	{

		tprintf("twh bkwl bt get BOARDING_OP_STATION_START\n");

		bkwl_msg_t msg;
		msg.param = (uint32_t)doorbell_boarding_info;
		msg.event = BKWL_WIFI_STATION_CONNECT;
		bkwl_event_send_msg(&msg);
	}
	break;
	case BOARDING_OP_SET_WIFI_PASSWORD_FINISH:
	{
		tprintf("twh bkwl bt get BOARDING_OP_SET_WIFI_PASSWORD_FINISH\n");

		bkwl_msg_t msg;
		msg.param = (uint32_t)doorbell_boarding_info;
		msg.event = BKWL_WIFI_STATION_BKWL_CONNECT;
		bkwl_event_send_msg(&msg);
	}
	break;
	case BOARDING_OP_SOFT_AP_START:
	{

		tprintf("twh bt BOARDING_OP_SOFT_AP_START\n");
		// doorbell_msg_t msg;

		// msg.event = DBEVT_WIFI_SOFT_AP_TURNING_ON;
		// msg.param = (uint32_t)doorbell_boarding_info;
		// doorbell_send_msg(&msg);
	}
	break;

	case BOARDING_OP_SERVICE_UDP_START:
	{

		tprintf("twh bt BOARDING_OP_SERVICE_UDP_START\n");
		// doorbell_msg_t msg;

		// msg.event = DBEVT_LAN_UDP_SERVICE_START_REQUEST;
		// msg.param = 0;
		// doorbell_send_msg(&msg);
	}
	break;

	case BOARDING_OP_SERVICE_TCP_START:
	{

		tprintf("twh bt BOARDING_OP_SET_CS2_DID\n");
		// doorbell_msg_t msg;
		// msg.event = DBEVT_LAN_TCP_SERVICE_START_REQUEST;
		// msg.param = 0;
		// doorbell_send_msg(&msg);
	}
	break;

	case BOARDING_OP_SET_CS2_DID:
	{

		tprintf("twh bt BOARDING_OP_SET_CS2_DID\n");

		// if (p2p_cs2_key == NULL)
		// {
		// 	p2p_cs2_key = os_malloc(sizeof(p2p_cs2_key_t));

		// 	if (p2p_cs2_key == NULL)
		// 	{
		// 		tprintf("malloc p2p_cs2_key\n");
		// 		break;
		// 	}

		// 	os_memset(p2p_cs2_key, 0, sizeof(p2p_cs2_key_t));
		// }

		// if (strlen(p2p_cs2_key->did))
		// {
		// 	tprintf("Already has did %s\n", p2p_cs2_key->did);
		// 	break;
		// }

		// if (length > sizeof(p2p_cs2_key->did))
		// {
		// 	tprintf("payload[%d] > did size[%d]\n", length, sizeof(p2p_cs2_key->did));
		// 	break;
		// }

		// os_memcpy(p2p_cs2_key->did, data, length);

		// tprintf("did: %s\n", p2p_cs2_key->did);

		// doorbell_boarding_event_message(opcode, BK_OK);
	}
	break;

	case BOARDING_OP_SET_CS2_APILICENSE:
	{

		tprintf("twh bt BOARDING_OP_SET_CS2_APILICENSE\n");

		// if (p2p_cs2_key == NULL)
		// {
		// 	p2p_cs2_key = os_malloc(sizeof(p2p_cs2_key_t));

		// 	if (p2p_cs2_key == NULL)
		// 	{
		// 		tprintf("malloc p2p_cs2_key\n");
		// 		break;
		// 	}

		// 	os_memset(p2p_cs2_key, 0, sizeof(p2p_cs2_key_t));
		// }

		// if (strlen(p2p_cs2_key->apilicense))
		// {
		// 	tprintf("Already has apilicense %s\n", p2p_cs2_key->apilicense);
		// 	break;
		// }

		// if (length > sizeof(p2p_cs2_key->apilicense))
		// {
		// 	tprintf("payload[%d] > apilicense size[%d]\n", length, sizeof(p2p_cs2_key->apilicense));
		// 	break;
		// }

		// os_memcpy(p2p_cs2_key->apilicense, data, length);

		// tprintf("apilicense: %s\n", p2p_cs2_key->apilicense);

		// doorbell_boarding_event_message(opcode, BK_OK);
	}
	break;

	case BOARDING_OP_SET_CS2_KEY:
	{

		tprintf("twh bt BOARDING_OP_SET_CS2_KEY\n");

		// if (p2p_cs2_key == NULL)
		// {
		// 	p2p_cs2_key = os_malloc(sizeof(p2p_cs2_key_t));

		// 	if (p2p_cs2_key == NULL)
		// 	{
		// 		tprintf("malloc p2p_cs2_key\n");
		// 		break;
		// 	}

		// 	os_memset(p2p_cs2_key, 0, sizeof(p2p_cs2_key_t));
		// }

		// if (strlen(p2p_cs2_key->key))
		// {
		// 	tprintf("Already key %s\n", p2p_cs2_key->key);
		// 	break;
		// }

		// if (length > sizeof(p2p_cs2_key->key))
		// {
		// 	tprintf("payload[%d] > key size[%d]\n", length, sizeof(p2p_cs2_key->key));
		// 	break;
		// }

		// os_memcpy(p2p_cs2_key->key, data, length);

		// tprintf("key: %s\n", p2p_cs2_key->key);

		// doorbell_boarding_event_message(opcode, BK_OK);
	}
	break;

	case BOARDING_OP_SET_CS2_INIT_STRING:
	{

		tprintf("twh bt BOARDING_OP_SET_CS2_INIT_STRING\n");

		// if (p2p_cs2_key == NULL)
		// {
		// 	p2p_cs2_key = os_malloc(sizeof(p2p_cs2_key_t));

		// 	if (p2p_cs2_key == NULL)
		// 	{
		// 		tprintf("malloc p2p_cs2_key\n");
		// 		break;
		// 	}

		// 	os_memset(p2p_cs2_key, 0, sizeof(p2p_cs2_key_t));
		// }

		// if (strlen(p2p_cs2_key->initstring))
		// {
		// 	tprintf("Already has initstring %s\n", p2p_cs2_key->initstring);
		// 	break;
		// }

		// if (length > sizeof(p2p_cs2_key->initstring))
		// {
		// 	tprintf("payload[%d] > initstring size[%d]\n", length, sizeof(p2p_cs2_key->initstring));
		// 	break;
		// }

		// os_memcpy(p2p_cs2_key->initstring, data, length);

		// tprintf("initstring: %s\n", p2p_cs2_key->initstring);

		// doorbell_boarding_event_message(opcode, BK_OK);
	}
	break;

	case BOARDING_OP_SRRVICE_CS2_START:
	{

		tprintf("twh bt BOARDING_OP_SRRVICE_CS2_START\n");

		// if (p2p_cs2_key == NULL)
		// {
		// 	tprintf("malloc p2p_cs2_key\n");
		// 	break;
		// }

		// if (p2p_cs2_key->cs2_started)
		// {
		// 	tprintf("CS2 already started  %x\n", p2p_cs2_key->cs2_started);
		// 	break;
		// }

		// strcat(p2p_cs2_key->apilicense, ":");
		// strcat(p2p_cs2_key->apilicense, p2p_cs2_key->key);
		// strcat(p2p_cs2_key->initstring, ":");
		// strcat(p2p_cs2_key->initstring, p2p_cs2_key->key);
		// p2p_cs2_key->cs2_started = true;

		// doorbell_msg_t msg;

		// msg.event = DBEVT_P2P_CS2_SERVICE_START_REQUEST;
		// msg.param = (uint32_t)p2p_cs2_key;
		// doorbell_send_msg(&msg);
	}
	break;

	case BOARDING_OP_BLE_DISABLE:
	{

		tprintf("twh bt BOARDING_OP_BLE_DISABLE\n");
		// doorbell_msg_t msg;
		// msg.event = DBEVT_BLE_DISABLE;
		// msg.param = 0;
		// doorbell_send_msg(&msg);
	}
	break;

	case BOARDING_OP_SET_WIFI_CHANNEL:
	{
		tprintf("twh bt BOARDING_OP_SET_WIFI_CHANNEL\n");

		uint16_t channel;
		STREAM_TO_UINT16(channel, data);
		tprintf(" get bt BOARDING_OP_SET_WIFI_CHANNEL: %u\n", channel);
	}
	break;
	}
}

int bkwl_bluetooth_init(void)
{
	uint8_t adv_data[ADV_MAX_SIZE] = {0};
	uint8_t adv_index = 0;
	uint8_t len_index = 0;
	uint8_t mac[6];
	int ret;

	tprintf("bkwl_bluetooth_init entry\n");
	/* flags */
	len_index = adv_index;
	adv_data[adv_index++] = 0x00;
	adv_data[adv_index++] = ADV_TYPE_FLAGS;
	adv_data[adv_index++] = 0x06;
	adv_data[len_index] = 2;
	tprintf("bkwl_bluetooth_init 1\n");

	/* local name */
	bk_bluetooth_get_address(mac);

	len_index = adv_index;
	adv_data[adv_index++] = 0x00;
	adv_data[adv_index++] = ADV_TYPE_LOCAL_NAME;

	ret = sprintf((char *)&adv_data[adv_index], "%s_%02X%02X%02X",
				  ADV_NAME_HEAD, mac[0], mac[1], mac[2]);

	adv_index += ret;
	adv_data[len_index] = ret + 1;

	/* 16bit uuid */
	len_index = adv_index;
	adv_data[adv_index++] = 0x00;
	adv_data[adv_index++] = ADV_TYPE_SERVICE_DATA;
	adv_data[adv_index++] = BOARDING_UUID & 0xFF;
	adv_data[adv_index++] = BOARDING_UUID >> 8;
	adv_data[len_index] = 3;
	tprintf("bkwl_bluetooth_init 2\n");

	/* manufacturer */
	len_index = adv_index;
	adv_data[adv_index++] = 0x00;
	adv_data[adv_index++] = ADV_TYPE_MANUFACTURER_SPECIFIC;
	adv_data[adv_index++] = BEKEN_COMPANY_ID & 0xFF;
	adv_data[adv_index++] = BEKEN_COMPANY_ID >> 8;
	adv_data[len_index] = 3;

	os_printf("adv data:\n");

	int i = 0;
	for (i = 0; i < adv_index; i++)
	{
		os_printf("%02X ", adv_data[i]);
	}

	os_printf("\n");

	if (doorbell_boarding_info == NULL)
	{
		doorbell_boarding_info = os_malloc(sizeof(doorbell_boarding_info_t));

		if (doorbell_boarding_info == NULL)
		{
			LOGE("doorbell_boarding_info malloc failed\n");

			goto error;
		}

		os_memset(doorbell_boarding_info, 0, sizeof(doorbell_boarding_info_t));
	}

	tprintf("twh doorbell_boarding_init 3\n");
	doorbell_boarding_info->boarding_info.cb = doorbell_boarding_operation_handle;

	ble_boarding_init(&doorbell_boarding_info->boarding_info);
	tprintf("bkwl_bluetooth_init 4\n");

	ble_boarding_adv_start(adv_data, adv_index);

	tprintf("bkwl_bluetooth_init exit\n");
	return BK_OK;
error:
	return BK_FAIL;
}

bk_err_t bkwl_get_bt_pair_data(char *jsonSrcData)
{

	bk_err_t ret = BK_OK;
	// {
	// 	"ssid": "Bokeweilai",
	// 	"password": "BKWL666666",
	// 	"token": "5d19612aa92c405a8eae054467d7bcd6",
	// 	"cl_token": "rJNUxRZU3YBTIb4B4EKJKfE2DrAAsn"
	// }
	tprintf("bkwl_get_bt_pair_data 1\n");

	cJSON *item = NULL;
	cJSON *root = cJSON_Parse(jsonSrcData);
	char *pValue = NULL;
	tprintf("bkwl_get_bt_pair_data 2\n");
	if (root != NULL)
	{
		tprintf("bkwl_get_bt_pair_data 3\n");
		item = cJSON_GetObjectItem(root, "ssid");
		if (item != NULL)
		{
			tprintf("bkwl_get_bt_pair_data 4\n");
			pValue = item->valuestring;
			strcpy(bkwl_main->bt.ssid, pValue);
			tprintf("bkwl_get_bt_pair_data ssid=%s\n", bkwl_main->bt.ssid);
		}
		item = cJSON_GetObjectItem(root, "password");
		if (item != NULL)
		{
			pValue = item->valuestring;
			strcpy(bkwl_main->bt.password, pValue);
			tprintf("bkwl_get_bt_pair_data password=%s\n", bkwl_main->bt.password);
		}
		item = cJSON_GetObjectItem(root, "token");
		if (item != NULL)
		{
			pValue = item->valuestring;
			strcpy(bkwl_main->bt.token, pValue);
			tprintf("bkwl_get_bt_pair_data token=%s\n", bkwl_main->bt.token);
		}
		item = cJSON_GetObjectItem(root, "cl_token");
		if (item != NULL)
		{
			pValue = item->valuestring;
			strcpy(bkwl_main->bt.cl_token, pValue);
			tprintf("bkwl_get_bt_pair_data cl_token=%s\n", bkwl_main->bt.cl_token);
		}
	}
	return ret;
}

bk_err_t bkwl_send_bt_pair_ack()
{
	bk_err_t ret = BK_OK;

	cJSON *root = NULL;
	char *out = NULL;

	// 	{
	// 	"ver": "2.0.22.2",
	// 	"act": "0001",
	// 	"sta": "00",
	// 	"token": "92c409d95b2e4574a106eb2284aed386",
	// 	"cl_device_id": "121d303ec89346111d46",
	// 	"cl_device_key": "071a3b297de7cdf3aeb8684f413b9a9e",
	// 	"seq_no": "88284135519821889520320148303148"
	// }

	tprintf("bkwl_send_bt_pair_ack entry\n");
	root = cJSON_CreateObject();
	cJSON_AddStringToObject(root, "ver", BKWL_IOT_VER_CUR);
	cJSON_AddStringToObject(root, "act", "0001");
	cJSON_AddStringToObject(root, "sta", "00");
	cJSON_AddStringToObject(root, "token", "92c409d95b2e4574a106eb2284aed386");
	cJSON_AddStringToObject(root, "cl_device_id", "121d303ec89346111d46");
	cJSON_AddStringToObject(root, "cl_device_key", "071a3b297de7cdf3aeb8684f413b9a9e");
	cJSON_AddStringToObject(root, "seq_no", "88284135519821889520320148303148");
	out = cJSON_Print(root);
	tprintf("bkwl_send_bt_pair_ack data=%s\n", out);
	ble_boarding_notify((uint8_t *)out, strlen(out));
	cJSON_Delete(root);
	free(out);
	tprintf("bkwl_send_bt_pair_ack exit\n");

	return ret;
}
